
//
// 120707 - AH - (Kryddar) Created.
//

package org.soekrat.server.orbsuppliers;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.soekrat.environment.Orb;
import org.soekrat.environment.OrbSupplier;
import org.soekrat.environment.RequestedSemanticEffects;
import org.soekrat.environment.RequestedSemanticEffects.RequestedSemanticEffect;
import org.soekrat.server.io.db.Account;
import org.soekrat.server.io.db.ConversationElement;
import org.soekrat.server.io.db.Folder;
import org.soekrat.server.io.db.SemanticEffect;
import org.soekrat.server.io.db.SoekratDAO;
import org.soekrat.server.io.db.SoekratDAOFactory;

/**
 * <p>
 *   {@link OrbSupplier} that ensure 
 *   {@link ConversationElement}, 
 *   {@link Account} exist and do initial initialization of the
 *   {@link Orb}.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class ConversationElementSupplier implements OrbSupplier 
{
  private final SoekratDAO m_dao=new SoekratDAOFactory().create();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public ConversationElementSupplier(){}

  // Specified in OrbSupplier.
  public String getEngineName(){ return null; }

  // Specified in OrbSupplier.
  public String supply(Orb orb, List<OrbSupplier> secondPass)
  {
    Long ceId=orb.getLong("ce-id");
    
    String visitor=orb.getString("visitor", "uknown");
    if (visitor==null)
    {
      return "ConversationElementSupplier: orb is missing visitor";
    }
    
    ConversationElement ce=(ceId==null) ? null : 
                                          m_dao.getConversationElement(ceId);
    if (ce==null)
    {
      ce=getDefaultConversationElement(visitor, orb);
    }
    else
    {
      RequestedSemanticEffects effects=getSemanticEffects(ce);
      orb.setAttribute("semantic-effects", effects);
    }
    
    ce.setAttributes(orb);
    
    orb.setAttribute("conversation-element", ce);
    
    RequestedSemanticEffects effects=getSemanticEffects(ce);
    orb.setAttribute("semantic-effects", effects);
    
    return null;
  }
  
  private ConversationElement getDefaultConversationElement(String visitor, 
    Orb orb)
  {
    Account account=getAccount(visitor, orb);
    
    Map<String, String> params=new HashMap<String, String>();
    params.put("engine", "soekrat2");
    
    ConversationElement ce=m_dao.createConversationElement(account, params);
    createDefSemanticEffects(ce);
    
    Folder rb=getRatbase();
    if (rb!=null)
    {
      ce.setParameter("rat-base-id", Long.toString(rb.id()));
    }
    
    orb.setAttribute("ce-id", ce.id());
    
    return ce;
  }
  
  private Account getAccount(String name, Orb orb)
  {
    Account retVal=m_dao.getAccount(name);
    
    if (retVal==null) 
    {
      retVal=m_dao.createAccount(name);
      orb.setAttribute("visitor", name);
    }
    
    return retVal;
  }
  
  private Folder getRatbase()
  {
    List<Folder> bases=m_dao.getRatBases();
    if (bases.isEmpty()) return null;
    Collections.shuffle(bases);
    return bases.get(0);
  }
  
  private void createDefSemanticEffects(ConversationElement ce)
  {
    String name="echo";
    String action="hear";
    m_dao.createSemanticEffect(ce, name, action);
    
    name="sequence";
    action="org.soekrat.engine.wheel.ontology.MineOntology, org.soekrat.engine.wheel.ontology.ForestOntology, org.soekrat.engine.wheel.ontology.NetworkOntology, org.soekrat.engine.wheel.ontology.ProductTableOntology";
    m_dao.createSemanticEffect(ce, name, action);
  }
  
  // Moved
  private RequestedSemanticEffects getSemanticEffects(ConversationElement ce)
  {
    SoekratDAO dao=new SoekratDAOFactory().create();
    
    RequestedSemanticEffects retVal=new RequestedSemanticEffects();
    
    List<SemanticEffect> effects=dao.getSemanticEffects(ce);
    
    for (SemanticEffect curr : effects) 
    {
      String name=curr.getName();
      
      RequestedSemanticEffect rse=retVal.create(name);
      rse.setData("action", curr.getParameter("action"));
    }
    
    return retVal;
  }
  
}
